<template>
  <div class="data-source-configuration">
    <TopNavigation :showTaskRoleSection="false" :showOrganizationSection="false" />

    <div class="page-header">
      <h2>数据源配置</h2>
      <button class="btn btn-primary"
        @click="() => { resetDataSourceConfig(); showDataSourceModal = true; }">配置数据源</button>
    </div>

    <!-- 居中提示弹窗组件 -->
    <div v-if="showAlert" class="alert-modal" @click="closeAlert">
      <div class="alert-modal-content" @click.stop>
        <div class="alert-modal-header">
          <h4>{{ alertTitle }}</h4>
        </div>
        <div class="alert-modal-body">
          <p>{{ alertMessage }}</p>
        </div>
        <div class="alert-modal-footer">
          <button class="btn btn-primary" @click="closeAlert">确定</button>
        </div>
      </div>
    </div>

    <!-- 居中确认对话框组件 -->
    <div v-if="showConfirm" class="alert-modal" @click="closeConfirm">
      <div class="alert-modal-content" @click.stop>
        <div class="alert-modal-header">
          <h4>{{ confirmTitle }}</h4>
        </div>
        <div class="alert-modal-body">
          <p>{{ confirmMessage }}</p>
        </div>
        <div class="alert-modal-footer">
          <button class="btn btn-secondary" @click="closeConfirm">取消</button>
          <button class="btn btn-danger" @click="confirmAction">确认删除</button>
        </div>
      </div>
    </div>

    <!-- 已保存的数据源配置列表 -->
    <div class="saved-configurations">
      <div class="card">
        <div class="toolbar">
          <h3>已保存的数据源配置</h3>
        </div>
        
        <div v-if="isLoading" class="loading-state">
          <div class="spinner"></div>
          <span>正在加载数据源配置...</span>
        </div>
        
        <!-- 数据源卡片展示 -->
        <div class="datasources-grid">
          <div v-for="(config, index) in paginatedConfigurations" :key="index" class="datasource-card">
            <div class="datasource-header">
              <div class="datasource-title-section">
                <h3 class="datasource-name">{{ config.name }}</h3>
                <span class="db-type">{{ config.dbConfig.dbType }}</span>
              </div>
              <div class="datasource-status">
                <span class="status-indicator active"></span>
              </div>
            </div>
            
            <div class="datasource-content">
              <div class="connection-info-section">
                <div class="section-title">连接信息</div>
                <div class="connection-details">
                  <div class="detail-item">
                    <span class="detail-label">主机:</span>
                    <span class="detail-value">{{ config.dbConfig.host }}:{{ config.dbConfig.port }}</span>
                  </div>
                  <div class="detail-item">
                    <span class="detail-label">数据库:</span>
                    <span class="detail-value">{{ config.dbConfig.database }}</span>
                  </div>
                  <div class="detail-item">
                    <span class="detail-label">创建时间:</span>
                    <span class="detail-value">{{ config.createdAt }}</span>
                  </div>
                </div>
              </div>
            </div>
            
            <div class="datasource-actions">
              <button class="btn btn-primary" @click="viewConfigDetails(index)">查看详情</button>
              <button class="btn btn-secondary" @click="editConfig(index)">编辑</button>
              <button class="btn btn-success" @click="syncDataSource(index)">同步</button>
              <button class="btn btn-danger" @click="deleteConfig(index)">删除</button>
            </div>
          </div>
        </div>

      <!-- 分页控件 -->
      <div v-if="savedConfigurations.length > 0" class="pagination-container">
        <button class="btn btn-default" @click="page = Math.max(1, page - 1)" :disabled="page === 1">
          上一页
        </button>
        <span class="page-info">
          第 {{ page }} 页 / 共 {{ Math.ceil(totalItems / pageSize) }} 页
        </span>
        <button class="btn btn-default" @click="page = Math.min(Math.ceil(totalItems / pageSize), page + 1)"
          :disabled="page === Math.ceil(totalItems / pageSize) || totalItems === 0">
          下一页
        </button>
        <div class="page-size-selector">
          <span>每页显示:</span>
          <select class="select" v-model="pageSize" @change="onPageSizeChange">
            <option value="5">5条</option>
            <option value="10">10条</option>
            <option value="20">20条</option>
            <option value="50">50条</option>
          </select>
        </div>
      </div>

        <p v-if="savedConfigurations.length === 0 && !isLoading" class="no-config-message">暂无保存的数据源配置</p>
      </div>
    </div>

    <!-- 数据源配置弹窗 -->
    <div v-if="showDataSourceModal" class="modal data-source-modal" @click="showDataSourceModal = false">
      <div class="modal-content data-source-modal-content" @click.stop>
        <div class="modal-header">
          <h3 class="modal-title">数据源配置</h3>
        </div>
        <div class="modal-body">
          <div class="card">
            <!-- 步骤导航 -->
            <div class="steps-container">
              <div class="step" :class="{ 'active': currentStep === 1, 'completed': currentStep > 1 }"
                @click="goToStep(1)">
                <div class="step-number">{{ currentStep > 1 ? '✓' : '1' }}</div>
                <div class="step-label">数据库配置</div>
              </div>
              <div class="step-separator" :class="{ 'completed': currentStep > 1 }"></div>
              <div class="step" :class="{ 'active': currentStep === 2, 'completed': currentStep > 2 }"
                @click="goToStep(2)">
                <div class="step-number">{{ currentStep > 2 ? '✓' : '2' }}</div>
                <div class="step-label">SQL查询</div>
              </div>
              <div class="step-separator" :class="{ 'completed': currentStep > 2 }"></div>
              <div class="step" :class="{ 'active': currentStep === 3, 'completed': currentStep > 3 }"
                @click="goToStep(3)">
                <div class="step-number">{{ currentStep > 3 ? '✓' : '3' }}</div>
                <div class="step-label">字段配置</div>
              </div>
              <div class="step-separator" :class="{ 'completed': currentStep > 3 }"></div>
              <div class="step" :class="{ 'active': currentStep === 4, 'completed': currentStep > 4 }"
                @click="goToStep(4)">
                <div class="step-number">{{ currentStep > 4 ? '✓' : '4' }}</div>
                <div class="step-label">定时任务</div>
              </div>
              <div class="step-separator" :class="{ 'completed': currentStep > 4 }"></div>
              <div class="step" :class="{ 'active': currentStep === 5, 'completed': currentStep > 5 }"
                @click="goToStep(5)">
                <div class="step-number">{{ currentStep > 5 ? '✓' : '5' }}</div>
                <div class="step-label">预览</div>
              </div>
            </div>

            <!-- 步骤内容 -->
            <div class="step-content">
              <!-- 步骤1: 数据库配置 -->
              <div v-if="currentStep === 1" class="database-configuration">
                <div class="form-item">
                  <label class="form-label">数据库类型</label>
                  <select class="select" v-model="dbConfig.dbType">
                    <option value="mysql">MySQL</option>
                    <option value="postgresql">PostgreSQL</option>
                    <option value="oracle">Oracle</option>
                    <option value="sqlserver">SQL Server</option>
                  </select>
                </div>
                <div class="form-item">
                  <label class="form-label">主机名</label>
                  <input type="text" class="input" v-model="dbConfig.host" placeholder="请输入主机名">
                </div>
                <div class="form-item">
                  <label class="form-label">端口</label>
                  <input type="number" class="input" v-model="dbConfig.port" placeholder="请输入端口号">
                </div>
                <div class="form-item">
                  <label class="form-label">数据库名称</label>
                  <input type="text" class="input" v-model="dbConfig.database" placeholder="请输入数据库名称">
                </div>
                <div class="form-item">
                  <label class="form-label">用户名</label>
                  <input type="text" class="input" v-model="dbConfig.username" placeholder="请输入用户名">
                </div>
                <div class="form-item">
                  <label class="form-label">密码</label>
                  <input type="password" class="input" v-model="dbConfig.password" placeholder="请输入密码">
                </div>
                <div class="form-item">
                  <label class="form-label">连接超时(秒)</label>
                  <input type="number" class="input" v-model="dbConfig.timeout" placeholder="请输入连接超时时间">
                </div>
                <div class="form-item">
                  <label class="form-label">配置名称</label>
                  <input type="text" class="input" v-model="configName" placeholder="请输入配置名称">
                </div>

                <div class="form-actions">
                  <button class="btn btn-primary" @click="testConnection">测试连接</button>
                </div>
              </div>

              <!-- 步骤2: SQL查询 -->
              <div v-if="currentStep === 2" class="sql-query">
                <div class="form-item">
                  <label class="form-label">SQL查询语句</label>
                  <textarea class="textarea" v-model="sqlQuery" placeholder="请输入SELECT查询语句" rows="10"></textarea>
                </div>
                <div class="form-actions">
                  <button class="btn btn-primary" @click="executeQuery">执行查询</button>
                </div>

                <!-- 查询结果预览 -->
                <div v-if="queryResults.length > 0" class="query-results">
                  <h3>查询结果预览</h3>
                  <div class="table-container">
                    <table class="table">
                      <thead>
                        <tr>
                          <th v-for="field in Object.keys(queryResults[0])" :key="field">{{ field }}</th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr v-for="(row, index) in queryResults.slice(0, 10)" :key="index">
                          <td v-for="field in Object.keys(row)" :key="field">{{ row[field] }}</td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                  <p class="result-count">共 {{ queryResults.length }} 条记录，显示前10条</p>
                </div>

              </div>

              <!-- 步骤3: 字段配置 -->
              <div v-if="currentStep === 3" class="field-configuration">
                <div class="table-container">
                  <table class="table">
                    <thead>
                      <tr>
                        <th>排序</th>
                        <th>字段名</th>
                        <th>显示名称</th>
                        <th>是否显示</th>
                        <th>是否主键</th>
                        <th>是否添加索引</th>
                        <th>搜索类型</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(field, index) in fields" :key="index">
                        <td>
                          <input type="number" class="input small" v-model="field.order" min="1">
                        </td>
                        <td>{{ field.name }}</td>
                        <td>
                          <input type="text" class="input" v-model="field.displayName">
                        </td>
                        <td>
                          <input type="checkbox" v-model="field.isDisplayed">
                        </td>
                        <td>
                          <input type="checkbox" v-model="field.isPrimaryKey">
                        </td>
                        <td>
                          <input type="checkbox" v-model="field.hasIndex">
                        </td>
                        <td>
                          <select class="select small" v-model="field.searchType" :disabled="!field.hasIndex">
                            <option value="text">文本搜索</option>
                            <option value="dropdown">下拉搜索</option>
                          </select>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>

                <!-- 添加字段选项 -->
                <div class="add-field-section">
                  <button class="btn btn-primary" @click="toggleAddFieldForm">
                    {{ showAddFieldForm ? '取消添加' : '添加字段' }}
                  </button>

                  <!-- 新建字段表单 - 仅在点击按钮后显示 -->
                  <div v-if="showAddFieldForm" class="add-field-form">
                    <h3>新建字段</h3>
                    <div class="form-grid">
                      <div class="form-item">
                        <label class="form-label">字段名</label>
                        <input type="text" class="input" v-model="newField.name" placeholder="请输入字段名">
                      </div>
                      <div class="form-item">
                        <label class="form-label">显示名称</label>
                        <input type="text" class="input" v-model="newField.displayName" placeholder="请输入显示名称">
                      </div>
                      <div class="form-item">
                        <label class="form-label">是否显示</label>
                        <input type="checkbox" v-model="newField.isDisplayed">
                      </div>
                      <div class="form-item">
                        <label class="form-label">是否主键</label>
                        <input type="checkbox" v-model="newField.isPrimaryKey">
                      </div>
                      <div class="form-item">
                        <label class="form-label">是否添加索引</label>
                        <input type="checkbox" v-model="newField.hasIndex">
                      </div>
                      <div class="form-item">
                        <label class="form-label">搜索类型</label>
                        <select class="select" v-model="newField.searchType" :disabled="!newField.hasIndex">
                          <option value="text">文本搜索</option>
                          <option value="dropdown">下拉搜索</option>
                        </select>
                      </div>
                    </div>
                    <div class="form-actions">
                      <button class="btn btn-primary" @click="addNewField">添加字段</button>
                    </div>
                  </div>
                </div>

              </div>

              <!-- 步骤4: 定时任务 -->
              <div v-if="currentStep === 4" class="schedule-configuration">
                <div class="form-item">
                  <label class="form-label">是否启用定时任务</label>
                  <input type="checkbox" v-model="scheduleConfig.enabled">
                </div>

                <div v-if="scheduleConfig.enabled" class="schedule-details">
                  <div class="form-item">
                    <label class="form-label">执行频率</label>
                    <select class="select" v-model="scheduleConfig.frequency" @change="onFrequencyChange">
                      <option value="minute">每分钟</option>
                      <option value="hour">每小时</option>
                      <option value="day">每天</option>
                      <option value="week">每周</option>
                      <option value="month">每月</option>
                      <option value="custom">自定义</option>
                    </select>
                  </div>

                  <div class="form-item">
                    <label class="form-label">间隔数量</label>
                    <input type="number" class="input" v-model="scheduleConfig.interval" min="1">
                  </div>

                  <div v-if="['day', 'week', 'month'].includes(scheduleConfig.frequency)" class="form-item">
                    <label class="form-label">执行时间范围</label>
                    <div class="time-range">
                      <input type="time" class="input" v-model="scheduleConfig.startTime">
                      <span class="time-range-separator">至</span>
                      <input type="time" class="input" v-model="scheduleConfig.endTime">
                    </div>
                  </div>

                  <div v-if="scheduleConfig.frequency === 'week'" class="form-item">
                    <label class="form-label">每周执行日</label>
                    <div class="checkbox-group">
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="1"> 周一</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="2"> 周二</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="3"> 周三</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="4"> 周四</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="5"> 周五</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="6"> 周六</label>
                      <label><input type="checkbox" v-model="scheduleConfig.daysOfWeek" :value="0"> 周日</label>
                    </div>
                  </div>

                  <div v-if="scheduleConfig.frequency === 'month'" class="form-item">
                    <label class="form-label">每月执行日</label>
                    <input type="number" class="input" v-model="scheduleConfig.daysOfMonth" min="1" max="31">
                  </div>

                  <div v-if="scheduleConfig.frequency === 'custom'" class="form-item">
                    <label class="form-label">Cron表达式</label>
                    <input type="text" class="input" v-model="scheduleConfig.cronExpression"
                      placeholder="例如: 0 0 * * *">
                  </div>
                </div>

              </div>

              <!-- 步骤5: 预览 -->
              <div v-if="currentStep === 5" class="preview">

                <!-- 任务基本信息 -->
                <div class="preview-section card">
                  <div class="card-header">
                    <h3 class="section-title">任务基本信息</h3>
                  </div>
                  <div class="card-body">
                    <div class="info-grid">
                      <div class="info-item">
                        <span class="info-label">配置名称:</span>
                        <span class="info-value">{{ configName || '未命名配置' }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">数据库类型:</span>
                        <span class="info-value">{{ dbConfig.dbType }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">主机名:</span>
                        <span class="info-value">{{ dbConfig.host }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">端口:</span>
                        <span class="info-value">{{ dbConfig.port }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">数据库名称:</span>
                        <span class="info-value">{{ dbConfig.database }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">用户名:</span>
                        <span class="info-value">{{ dbConfig.username }}</span>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 查询配置 -->
                <div class="preview-section card">
                  <div class="card-header">
                    <h3 class="section-title">查询配置</h3>
                  </div>
                  <div class="card-body">
                    <div class="sql-query-preview">
                      <pre class="sql-code">{{ sqlQuery || '暂无SQL查询语句' }}</pre>
                    </div>
                    <div class="query-stats">
                      <div class="stat-item">
                        <div class="stat-label">查询结果数量</div>
                        <div class="stat-value">{{ queryResults.length }} 条</div>
                      </div>
                      <div class="stat-item">
                        <div class="stat-label">查询字段数量</div>
                        <div class="stat-value">{{ queryResults.length > 0 ? Object.keys(queryResults[0]).length : 0 }}
                          个</div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 字段配置 -->
                <div class="preview-section card">
                  <div class="card-header">
                    <h3 class="section-title">字段配置</h3>
                  </div>
                  <div class="card-body">
                    <div class="field-stats">
                      <div class="stat-item">
                        <div class="stat-label">总字段数</div>
                        <div class="stat-value">{{ fields.length }} 个</div>
                      </div>
                      <div class="stat-item">
                        <div class="stat-label">显示字段数</div>
                        <div class="stat-value">{{fields.filter(field => field.isDisplayed).length}} 个</div>
                      </div>
                      <div class="stat-item">
                        <div class="stat-label">主键字段数</div>
                        <div class="stat-value">{{fields.filter(field => field.isPrimaryKey).length}} 个</div>
                      </div>
                      <div class="stat-item">
                        <div class="stat-label">索引字段数</div>
                        <div class="stat-value">{{fields.filter(field => field.hasIndex).length}} 个</div>
                      </div>
                    </div>
                    <div class="table-container field-table">
                      <table class="table">
                        <thead>
                          <tr>
                            <th>字段名</th>
                            <th>显示名称</th>
                            <th>是否显示</th>
                            <th>是否主键</th>
                            <th>是否索引</th>
                            <th>搜索类型</th>
                          </tr>
                        </thead>
                        <tbody>
                          <tr v-for="(field, index) in fields" :key="index">
                            <td>{{ field.name }}</td>
                            <td>{{ field.displayName || field.name }}</td>
                            <td>
                              <span class="status-badge"
                                :class="{ 'status-active': field.isDisplayed, 'status-inactive': !field.isDisplayed }">
                                {{ field.isDisplayed ? '是' : '否' }}
                              </span>
                            </td>
                            <td>
                              <span class="status-badge"
                                :class="{ 'status-active': field.isPrimaryKey, 'status-inactive': !field.isPrimaryKey }">
                                {{ field.isPrimaryKey ? '是' : '否' }}
                              </span>
                            </td>
                            <td>
                              <span class="status-badge"
                                :class="{ 'status-active': field.hasIndex, 'status-inactive': !field.hasIndex }">
                                {{ field.hasIndex ? '是' : '否' }}
                              </span>
                            </td>
                            <td>
                              <template v-if="field.searchType === 'text'">文本搜索</template>
                              <template v-else-if="field.searchType === 'dropdown'">下拉搜索</template>
                              <template v-else>无</template>
                            </td>
                          </tr>
                        </tbody>
                      </table>
                    </div>
                  </div>
                </div>

                <!-- 定时任务配置 -->
                <div class="preview-section card">
                  <div class="card-header">
                    <h3 class="section-title">定时任务配置</h3>
                  </div>
                  <div class="card-body">
                    <div class="schedule-config">
                      <div class="info-item">
                        <span class="info-label">是否启用:</span>
                        <span class="status-badge"
                          :class="{ 'status-active': scheduleConfig.enabled, 'status-inactive': !scheduleConfig.enabled }">
                          {{ scheduleConfig.enabled ? '是' : '否' }}
                        </span>
                      </div>
                      <template v-if="scheduleConfig.enabled">
                        <div class="info-item">
                          <span class="info-label">执行频率:</span>
                          <span class="info-value">
                            {{ scheduleConfig.frequency === 'minute' ? '每分钟' :
                              scheduleConfig.frequency === 'hour' ? '每小时' :
                                scheduleConfig.frequency === 'day' ? '每天' :
                                  scheduleConfig.frequency === 'week' ? '每周' :
                                    scheduleConfig.frequency === 'month' ? '每月' : '自定义' }}
                          </span>
                        </div>
                        <div class="info-item">
                          <span class="info-label">间隔数量:</span>
                          <span class="info-value">{{ scheduleConfig.interval }}</span>
                        </div>
                        <div v-if="['day', 'week', 'month'].includes(scheduleConfig.frequency)" class="info-item">
                          <span class="info-label">执行时间范围:</span>
                          <span class="info-value">{{ scheduleConfig.startTime }} 至 {{ scheduleConfig.endTime }}</span>
                        </div>
                        <div v-if="scheduleConfig.frequency === 'week'" class="info-item">
                          <span class="info-label">每周执行日:</span>
                          <span class="info-value">
                            {{scheduleConfig.daysOfWeek.length > 0 ?
                              scheduleConfig.daysOfWeek.map(day => ['周日', '周一', '周二', '周三', '周四', '周五',
                                '周六'][day]).join('、') :
                            '未选择' }}
                          </span>
                        </div>
                        <div v-if="scheduleConfig.frequency === 'month'" class="info-item">
                          <span class="info-label">每月执行日:</span>
                          <span class="info-value">{{ scheduleConfig.daysOfMonth }}</span>
                        </div>
                        <div v-if="scheduleConfig.frequency === 'custom'" class="info-item">
                          <span class="info-label">Cron表达式:</span>
                          <span class="info-value">{{ scheduleConfig.cronExpression || '未设置' }}</span>
                        </div>
                        <div class="info-item schedule-description">
                          <span class="info-label">任务描述:</span>
                          <span class="info-value">{{ getScheduleInfo() }}</span>
                        </div>
                      </template>
                    </div>
                  </div>
                </div>


              </div>
            </div>

            <!-- 操作按钮 -->
            <div class="action-buttons">
              <button class="btn btn-secondary" @click="showDataSourceModal = false">取消</button>
              <button class="btn btn-default" @click="prevStep" :disabled="currentStep === 1">上一步</button>
              <button class="btn btn-primary" @click="currentStep === 5 ? saveDataSourceConfig() : nextStep()"
                :disabled="currentStep === 5 ? false : !canProceed">
                {{ currentStep === 5 ? '完成' : '下一步' }}
              </button>
            </div>
            ``
          </div>
        </div>
      </div>
    </div>

    <!-- 数据详情模态框 -->
    <div v-if="showDetailsModal" class="modal" @click="closeDetailsModal">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3 class="modal-title">数据详情</h3>
          <button class="btn btn-default" @click="closeDetailsModal">×</button>
        </div>
        <div class="modal-body">
          <div v-for="(value, key) in selectedRow" :key="key" class="detail-item">
            <span class="detail-label">{{ getFieldDisplayName(key) }}:</span>
            <span class="detail-value">
              <template v-if="typeof value === 'object' && value !== null">
                <pre class="json-preview">{{ JSON.stringify(value, null, 2) }}</pre>
              </template>
              <template v-else-if="typeof value === 'boolean'">{{ value ? '是' : '否' }}</template>
              <template v-else-if="value === undefined || value === null">空</template>
              <template v-else>{{ value }}</template>
            </span>
            <button class="copy-btn" @click="copyToClipboard(value, $event)">复制</button>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-primary" @click="copyAllDetails()">复制全部</button>
          <button class="btn btn-primary" @click="closeDetailsModal">关闭</button>
        </div>
      </div>
    </div>

    <!-- 配置详情模态框 -->
    <div v-if="showConfigDetailsModal" class="modal" @click="closeConfigDetailsModal">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3 class="modal-title">配置详情</h3>
          <button class="btn btn-default" @click="closeConfigDetailsModal">×</button>
        </div>
        <div class="modal-body">
          <div class="detail-section">
            <h4>基本信息</h4>
            <div class="detail-item">
              <span class="detail-label">配置名称:</span>
              <span class="detail-value">{{ selectedConfig.name }}</span>
              <button class="copy-btn" @click="copyToClipboard(selectedConfig.name, $event)">复制</button>
            </div>
            <div class="detail-item">
              <span class="detail-label">创建时间:</span>
              <span class="detail-value">{{ selectedConfig.createdAt }}</span>
            </div>
          </div>

          <div class="detail-section">
            <h4>数据库配置</h4>
            <div class="detail-item">
              <span class="detail-label">数据库类型:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.dbType }}</span>
            </div>
            <div class="detail-item">
              <span class="detail-label">主机名:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.host }}</span>
              <button class="copy-btn" @click="copyToClipboard(selectedConfig.dbConfig.host, $event)">复制</button>
            </div>
            <div class="detail-item">
              <span class="detail-label">端口:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.port }}</span>
            </div>
            <div class="detail-item">
              <span class="detail-label">数据库名称:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.database }}</span>
              <button class="copy-btn" @click="copyToClipboard(selectedConfig.dbConfig.database, $event)">复制</button>
            </div>
            <div class="detail-item">
              <span class="detail-label">用户名:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.username }}</span>
              <button class="copy-btn" @click="copyToClipboard(selectedConfig.dbConfig.username, $event)">复制</button>
            </div>
            <div class="detail-item">
              <span class="detail-label">密码:</span>
              <span class="detail-value">******</span>
              <button class="copy-btn"
                @click="copyToClipboard(selectedConfig.dbConfig.password || '密码未设置', $event)">复制</button>
            </div>
            <div class="detail-item">
              <span class="detail-label">连接超时:</span>
              <span class="detail-value">{{ selectedConfig.dbConfig.timeout }} 秒</span>
            </div>
          </div>

          <div class="detail-section">
            <h4>SQL查询</h4>
            <div class="detail-item sql-query">
              <pre>{{ selectedConfig.sqlQuery }}</pre>
              <button class="copy-btn sql-copy-btn"
                @click="copyToClipboard(selectedConfig.sqlQuery, $event)">复制SQL</button>
            </div>
          </div>

          <div class="detail-section">
            <h4>字段配置</h4>
            <div class="table-container">
              <table class="table">
                <thead>
                  <tr>
                    <th>字段名</th>
                    <th>显示名称</th>
                    <th>是否显示</th>
                    <th>搜索类型</th>
                    <th>是否索引</th>
                    <th>排序</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(field, index) in selectedConfig.fields" :key="index">
                    <td>{{ field.name }}</td>
                    <td>{{ field.displayName }}</td>
                    <td>{{ field.isDisplayed ? '是' : '否' }}</td>
                    <td>{{ field.searchType === 'text' ? '文本搜索' : field.searchType === 'dropdown' ? '下拉搜索' : '无搜索' }}
                    </td>
                    <td>{{ field.hasIndex ? '是' : '否' }}</td>
                    <td>{{ field.order || '-' }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>

          <div class="detail-section">
            <h4>定时任务配置</h4>
            <div class="detail-item">
              <span class="detail-label">是否启用:</span>
              <span class="detail-value">{{ selectedConfig.scheduleConfig.enabled ? '是' : '否' }}</span>
            </div>
            <div v-if="selectedConfig.scheduleConfig.enabled" class="schedule-details">
              <div class="detail-item">
                <span class="detail-label">执行频率:</span>
                <span class="detail-value">{{ selectedConfig.scheduleConfig.frequency === 'minute' ? '每分钟' :
                  selectedConfig.scheduleConfig.frequency === 'hour' ? '每小时' : selectedConfig.scheduleConfig.frequency
                    ===
                    'day' ? '每天' : selectedConfig.scheduleConfig.frequency === 'week' ? '每周' :
                  selectedConfig.scheduleConfig.frequency === 'month' ? '每月' : '自定义' }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">间隔数量:</span>
                <span class="detail-value">{{ selectedConfig.scheduleConfig.interval }}</span>
              </div>
              <div v-if="['day', 'week', 'month'].includes(selectedConfig.scheduleConfig.frequency)"
                class="detail-item">
                <span class="detail-label">执行时间范围:</span>
                <span class="detail-value">{{ selectedConfig.scheduleConfig.startTime }} 至 {{
                  selectedConfig.scheduleConfig.endTime }}</span>
              </div>
              <div v-if="selectedConfig.scheduleConfig.frequency === 'week'" class="detail-item">
                <span class="detail-label">每周执行日:</span>
                <span class="detail-value">{{selectedConfig.scheduleConfig.daysOfWeek.length > 0 ?
                  selectedConfig.scheduleConfig.daysOfWeek.map(day => ['周日', '周一', '周二', '周三', '周四', '周五',
                  '周六'][day]).join('、') : '未选择' }}</span>
              </div>
              <div v-if="selectedConfig.scheduleConfig.frequency === 'month'" class="detail-item">
                <span class="detail-label">每月执行日:</span>
                <span class="detail-value">{{ selectedConfig.scheduleConfig.daysOfMonth }}</span>
              </div>
              <div v-if="selectedConfig.scheduleConfig.frequency === 'custom'" class="detail-item">
                <span class="detail-label">Cron表达式:</span>
                <span class="detail-value">{{ selectedConfig.scheduleConfig.cronExpression || '未设置' }}</span>
                <button class="copy-btn"
                  @click="copyToClipboard(selectedConfig.scheduleConfig.cronExpression || '')">复制</button>
              </div>
              <div class="detail-item">
                <span class="detail-label">任务描述:</span>
                <span class="detail-value">{{ getScheduleInfo() }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-secondary" @click="copyAllConfigDetails()">复制全部</button>
          <button class="btn btn-primary" @click="closeConfigDetailsModal">关闭</button>
        </div>
      </div>
    </div>

    <!-- 同步数据源弹窗 -->
    <div v-if="showSyncDataSourceModal" class="modal">
      <div class="modal-content" style="max-width: 900px; max-height: 90vh;">
        <div class="modal-header">
          <h2 class="modal-title">数据源同步 - {{ syncDataSourceConfig.name }}</h2>
          <button class="btn btn-default" @click="closeSyncDataSourceModal">关闭</button>
        </div>

        <div class="modal-body" style="overflow-y: auto;">
          <div class="sync-content">
            <!-- 数据源基本信息 -->
            <div class="sync-section sync-basic-info">
              <div class="preview-section card">
                <div class="card-header">
                  <h3 class="section-title">基本信息</h3>
                </div>
                <div class="card-body">
                  <div class="info-grid">
                    <div class="info-item">
                      <span class="info-label">配置名称:</span>
                      <span class="info-value">{{ syncDataSourceConfig.name }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">数据库类型:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.dbType || '-' }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">创建时间:</span>
                      <span class="info-value">{{ syncDataSourceConfig.createdAt || '-' }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 数据库配置 -->
            <div class="sync-section sync-database-config">
              <div class="preview-section card">
                <div class="card-header">
                  <h3 class="section-title">数据库配置</h3>
                </div>
                <div class="card-body">
                  <div class="info-grid">
                    <div class="info-item">
                      <span class="info-label">主机地址:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.host || '-' }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">端口号:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.port || '-' }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">数据库名:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.database || '-' }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">用户名:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.username || '-' }}</span>
                    </div>
                    <div class="info-item">
                      <span class="info-label">连接超时:</span>
                      <span class="info-value">{{ syncDataSourceConfig.dbConfig?.timeout || 30 }}秒</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- SQL查询 -->
            <div class="sync-section sync-sql-query">
              <div class="preview-section card">
                <div class="card-header">
                  <h3 class="section-title">SQL查询</h3>
                </div>
                <div class="card-body">
                  <div class="sql-query-preview">
                    <pre class="sql-code">{{ syncDataSourceConfig.sqlQuery || '-' }}</pre>
                  </div>
                </div>
              </div>
            </div>

            <!-- 字段配置 -->
            <div class="sync-section sync-field-config">
              <div class="preview-section card">
                <div class="card-header">
                  <h3 class="section-title">字段配置</h3>
                </div>
                <div class="card-body">
                  <div class="field-stats">
                    <div class="stat-item">
                      <div class="stat-label">总字段数</div>
                      <div class="stat-value">{{ syncDataSourceConfig.fields?.length || 0 }} 个</div>
                    </div>
                    <div class="stat-item">
                      <div class="stat-label">显示字段数</div>
                      <div class="stat-value">{{syncDataSourceConfig.fields?.filter(field => field.isDisplayed).length
                        || 0
                        }} 个</div>
                    </div>
                    <div class="stat-item">
                      <div class="stat-label">主键字段数</div>
                      <div class="stat-value">{{syncDataSourceConfig.fields?.filter(field => field.isPrimaryKey).length
                        ||
                        0 }} 个</div>
                    </div>
                    <div class="stat-item">
                      <div class="stat-label">索引字段数</div>
                      <div class="stat-value">{{syncDataSourceConfig.fields?.filter(field => field.hasIndex).length ||
                        0 }}
                        个</div>
                    </div>
                  </div>
                  <div class="table-container field-table">
                    <table class="table">
                      <thead>
                        <tr>
                          <th>字段名</th>
                          <th>显示名称</th>
                          <th>是否显示</th>
                          <th>是否主键</th>
                          <th>是否索引</th>
                          <th>搜索类型</th>
                          <th>排序</th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr v-for="(field, index) in syncDataSourceConfig.fields" :key="index">
                          <td>{{ field.name }}</td>
                          <td>{{ field.displayName }}</td>
                          <td>{{ field.isDisplayed ? '是' : '否' }}</td>
                          <td>{{ field.isPrimaryKey ? '是' : '否' }}</td>
                          <td>{{ field.hasIndex ? '是' : '否' }}</td>
                          <td>{{ field.searchType === 'text' ? '文本搜索' : field.searchType === 'dropdown' ? '下拉搜索' : '无搜索'
                            }}
                          </td>
                          <td>{{ field.order || '-' }}</td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
            </div>

            <!-- 定时任务配置 -->
            <div class="sync-section sync-schedule-config">
              <div class="preview-section card">
                <div class="card-header">
                  <h3 class="section-title">定时任务配置</h3>
                </div>
                <div class="card-body">
                  <div class="info-grid">
                    <div class="info-item">
                      <span class="info-label">是否启用:</span>
                      <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.enabled ? '是' : '否' }}</span>
                    </div>
                    <div v-if="syncDataSourceConfig.scheduleConfig?.enabled" class="schedule-details">
                      <div class="info-item">
                        <span class="info-label">执行频率:</span>
                        <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.frequency === 'minute' ? '每分钟'
                          :
                          syncDataSourceConfig.scheduleConfig?.frequency === 'hour' ? '每小时' :
                            syncDataSourceConfig.scheduleConfig?.frequency === 'day' ? '每天' :
                              syncDataSourceConfig.scheduleConfig?.frequency === 'week' ? '每周' :
                          syncDataSourceConfig.scheduleConfig?.frequency === 'month' ? '每月' : '自定义' }}</span>
                      </div>
                      <div class="info-item">
                        <span class="info-label">间隔数量:</span>
                        <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.interval || '-' }}</span>
                      </div>
                      <div v-if="['day', 'week', 'month'].includes(syncDataSourceConfig.scheduleConfig?.frequency)"
                        class="info-item">
                        <span class="info-label">执行时间范围:</span>
                        <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.startTime }} 至 {{
                          syncDataSourceConfig.scheduleConfig?.endTime }}</span>
                      </div>
                      <div v-if="syncDataSourceConfig.scheduleConfig?.frequency === 'week'" class="info-item">
                        <span class="info-label">每周执行日:</span>
                        <span class="info-value">{{syncDataSourceConfig.scheduleConfig?.daysOfWeek?.length > 0 ?
                          syncDataSourceConfig.scheduleConfig.daysOfWeek.map(day => ['周日', '周一', '周二', '周三', '周四', '周五',
                          '周六'][day]).join('、') : '未选择' }}</span>
                      </div>
                      <div v-if="syncDataSourceConfig.scheduleConfig?.frequency === 'month'" class="info-item">
                        <span class="info-label">每月执行日:</span>
                        <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.daysOfMonth || '-' }}</span>
                      </div>
                      <div v-if="syncDataSourceConfig.scheduleConfig?.frequency === 'custom'" class="info-item">
                        <span class="info-label">Cron表达式:</span>
                        <span class="info-value">{{ syncDataSourceConfig.scheduleConfig?.cronExpression || '未设置'
                          }}</span>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- SQL查询结果 -->
            <div class="sync-section sync-query-results">
              <div v-if="isSyncing" class="loading-state">
                <p>正在同步数据...</p>
              </div>
              <div v-else-if="syncDataSourceResults.length > 0">
                <div class="success-message">
                  <p>数据同步成功</p>
                </div>
              </div>
              <div v-else class="no-results">
                <p>暂无查询结果</p>
              </div>
            </div>
          </div>
        </div>

        <div class="modal-footer">
          <button class="btn btn-primary" @click="syncDataSourceConfigToBackend"
            :disabled="isSubmittingTask">同步数据源配置</button>
          <button class="btn btn-success" @click="syncTaskFromDataSource"
            :disabled="isSyncingTask">同步任务</button>
          <button class="btn btn-default" @click="closeSyncDataSourceModal">关闭</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import TopNavigation from '../components/TopNavigation.vue'
import { ref, computed, watch } from 'vue'
import { post, get, del } from '../utils/request'

// 控制数据源配置弹窗显示
const showDataSourceModal = ref(false)

// 配置详情模态框相关
const selectedConfig = ref({})
const showConfigDetailsModal = ref(false)

// 同步数据源相关
const syncDataSourceConfig = ref({})
const syncDataSourceResults = ref([])
const showSyncDataSourceModal = ref(false)
const isSyncing = ref(false)

// 已保存的数据源配置列表
const savedConfigurations = ref([])

// 加载状态
const isLoading = ref(false)

// 分页相关变量
const page = ref(1)
const pageSize = ref(10)

// 处理分页大小变化
const onPageSizeChange = () => {
  // 重置到第一页
  page.value = 1;
}

// 分页相关计算属性
const totalItems = computed(() => savedConfigurations.value.length)
const paginatedConfigurations = computed(() => {
  const startIndex = (page.value - 1) * pageSize.value
  return savedConfigurations.value.slice(startIndex, startIndex + pageSize.value)
})

// 从后端API获取数据源配置
const fetchDataSources = async () => {
  isLoading.value = true
  try {
    // 调用后端API获取数据源列表
    const response = await get('/api/data-sources')

    // 处理响应
    if (response.code === 200 && response.data && Array.isArray(response.data)) {
      // 将后端返回的数据转换为前端需要的格式
      const formattedDataSources = response.data.map(dataSource => ({
        id: dataSource.id,
        name: dataSource.name,
        createdAt: new Date(dataSource.createdAt).toLocaleString(),
        updatedAt: dataSource.updatedAt ? new Date(dataSource.updatedAt).toLocaleString() : '',
        dbConfig: {
          dbType: dataSource.dbType,
          host: dataSource.host,
          port: dataSource.port,
          database: dataSource.databaseName,
          username: dataSource.username,
          password: '', // 不从后端获取密码
          timeout: 30
        },
        sqlQuery: dataSource.querySql,
        fields: [], // 初始化空字段数组，实际使用时可以根据需要解析
        scheduleConfig: {
          enabled: dataSource.scheduleEnabled === 1,
          frequency: 'custom',
          cronExpression: dataSource.scheduleCron,
          startTime: '00:00',
          endTime: '23:59',
          daysOfWeek: [],
          daysOfMonth: 1,
          interval: 1
        },
        queryResults: [] // 初始化空结果数组
      }))

      // 更新数据源配置列表
      savedConfigurations.value = formattedDataSources

      // 确保分页状态正确，避免删除后出现空白页面
      // 如果当前页大于总页数，则重置到最后一页
      const totalPages = Math.ceil(savedConfigurations.value.length / pageSize.value)
      if (page.value > totalPages && totalPages > 0) {
        page.value = totalPages
      }

      // 保存到localStorage作为缓存
      try {
        localStorage.setItem('dataSourceConfigurations', JSON.stringify(formattedDataSources))
      } catch (error) {
        console.error('Failed to save configurations to localStorage:', error)
      }
    } else {
      console.warn('Invalid response format from data sources API')
      // 如果API调用失败，尝试从localStorage加载
      loadFromLocalStorage()
    }
  } catch (error) {
    console.error('Failed to fetch data sources from API:', error)
    showCustomAlert('获取数据源配置失败，请检查网络连接', '错误', 'error')
    // 如果API调用失败，尝试从localStorage加载
    loadFromLocalStorage()
  } finally {
    isLoading.value = false
  }
}

// 从localStorage加载数据源配置
const loadFromLocalStorage = () => {
  try {
    const saved = localStorage.getItem('dataSourceConfigurations')
    if (saved) {
      savedConfigurations.value = JSON.parse(saved)
    }
  } catch (error) {
    console.error('Failed to load saved configurations from localStorage:', error)
    savedConfigurations.value = []
  }
}

// 组件加载时获取数据源配置
fetchDataSources()

// 当前是否处于编辑模式和编辑的索引
const isEditing = ref(false)
const editingIndex = ref(-1)

// 重置数据源配置
const resetDataSourceConfig = () => {
  // 重置当前步骤到第一步
  currentStep.value = 1

  // 重置配置名称
  configName.value = '123'

  // 重置编辑状态
  isEditing.value = false
  editingIndex.value = -1

  // 重置数据库配置
  dbConfig.value = {
    dbType: 'mysql',
    host: '192.168.78.213',
    port: 3306,
    database: 'vardb',
    username: 'vardb_user',
    password: 'vardb_pass',
    timeout: 30
  }

  // 重置SQL查询
  sqlQuery.value = 'select * from users'
  queryResults.value = []

  // 重置字段配置
  fields.value = []
  newField.value = {
    name: '',
    displayName: '',
    isDisplayed: true,
    hasIndex: false,
    searchType: 'text',
    order: 0
  }
  showAddFieldForm.value = false

  // 重置定时任务配置
  scheduleConfig.value = {
    enabled: false,
    frequency: 'hour',
    interval: 1,
    startTime: '00:00',
    endTime: '23:59',
    daysOfWeek: [],
    daysOfMonth: 1,
    cronExpression: ''
  }

  // 重置预览数据
  previewData.value = []
  filteredPreviewData.value = []

  // 重置搜索过滤
  searchFilters.value = {}
}

// 配置名称
const configName = ref('123')

// 将定时任务配置转换为cron表达式
const convertToCronExpression = () => {
  if (!scheduleConfig.value.enabled) return ''

  const { frequency, interval, startTime, endTime, daysOfWeek, daysOfMonth, cronExpression } = scheduleConfig.value

  // 如果是自定义cron表达式，直接返回
  if (frequency === 'custom' && cronExpression) {
    return cronExpression
  }

  // 解析开始时间
  const [startHour, startMinute] = startTime.split(':').map(Number)

  switch (frequency) {
    case 'minute':
      // 每X分钟执行一次: */X * * * *
      return `*/${interval} * * * *`

    case 'hour':
      // 每X小时在第startMinute分钟执行: startMinute */X * * *
      return `${startMinute} */${interval} * * *`

    case 'day':
      // 每X天在startHour:startMinute执行: startMinute startHour */X * *
      return `${startMinute} ${startHour} */${interval} * *`

    case 'week':
      // 每X周的指定星期几在startHour:startMinute执行: startMinute startHour * * 星期几(多个用逗号分隔)
      if (daysOfWeek.length === 0) {
        // 如果没有选择星期几，默认每周一执行
        return `${startMinute} ${startHour} * * 1`
      }
      // cron表达式中星期几从0(周日)到6(周六)
      return `${startMinute} ${startHour} * * ${daysOfWeek.join(',')}`

    case 'month':
      // 每X个月的指定日期在startHour:startMinute执行: startMinute startHour daysOfMonth */X *
      return `${startMinute} ${startHour} ${daysOfMonth} */${interval} *`

    default:
      return ''
  }
}

// 保存数据源配置
const saveDataSourceConfig = async () => {
  try {
    // 构建符合后端接口要求的数据对象
    const requestData = {
      name: configName.value.trim() || `数据源配置_${new Date().getTime()}`,
      dbType: dbConfig.value.dbType,
      host: dbConfig.value.host,
      port: dbConfig.value.port,
      username: dbConfig.value.username,
      password: dbConfig.value.password, // 使用password字段名
      databaseName: dbConfig.value.database,
      querySql: sqlQuery.value,
      idFields: JSON.stringify(fields.value.filter(field => field.isPrimaryKey).map(field => field.name)), // 使用用户配置的主键字段
      displayFields: JSON.stringify(fields.value
        .filter(field => field.isDisplayed)
        .map(field => field.name)
      ),
      extraFields: JSON.stringify({ "remark": "生产产品数据" }), // 添加备注信息
      dropdownFields: JSON.stringify(fields.value
        .filter(field => field.searchType === 'dropdown')
        .map(field => ({
          name: field.name,
          label: field.displayName || field.name,
          options: getDropdownOptions(field.name)
        }))
      ),
      searchableFields: JSON.stringify(fields.value
        .filter(field => field.searchType !== 'none')
        .map(field => ({
          name: field.name,
          type: field.searchType === 'dropdown' ? 'dropdown' : 'fuzzy',
          label: field.displayName || field.name
        }))
      ),
      status: 1, // 1表示启用
      scheduleEnabled: scheduleConfig.value.enabled ? 1 : 0,
      scheduleCron: convertToCronExpression(),
      scheduleDesc: scheduleConfig.value.enabled ? getScheduleInfo() : ''
    }

    // 调用后端API
    const response = await post('/api/data-sources', requestData)

    // 处理响应
    if (response.code === 200) {
      // 创建配置对象用于本地存储
      const configData = {
        name: requestData.name,
        dbConfig: { ...dbConfig.value },
        sqlQuery: sqlQuery.value,
        fields: [...fields.value],
        scheduleConfig: { ...scheduleConfig.value }
      }

      if (isEditing.value && editingIndex.value !== -1) {
        // 在编辑模式下，更新现有配置
        const originalConfig = savedConfigurations.value[editingIndex.value]
        configData.createdAt = originalConfig.createdAt // 保留原始创建时间
        savedConfigurations.value[editingIndex.value] = configData
        showCustomAlert('配置已成功更新', '成功', 'success')
      } else {
        // 在创建模式下，添加新配置
        configData.createdAt = new Date().toLocaleString()
        savedConfigurations.value.push(configData)
        showCustomAlert('配置已成功保存', '成功', 'success')
      }

      // 保存到localStorage
      try {
        localStorage.setItem('dataSourceConfigurations', JSON.stringify(savedConfigurations.value))
      } catch (error) {
        console.error('Failed to save configurations to localStorage:', error)
      }

      // 重置编辑状态
      isEditing.value = false
      editingIndex.value = -1

      // 关闭模态框
      showDataSourceModal.value = false
    } else {
      showCustomAlert(`保存失败: ${response.message || '未知错误'}`, '错误', 'error')
    }
  } catch (error) {
    console.error('保存数据源配置失败:', error)
    showCustomAlert(`保存失败: ${error.message || '网络错误或服务器不可用'}`, '错误', 'error')
  }
}

// 查看配置详情
const viewConfigDetails = (index) => {
  // 设置当前查看的配置
  selectedConfig.value = JSON.parse(JSON.stringify(savedConfigurations.value[index])) // 使用深拷贝避免修改原始数据
  // 确保显示配置详情模态框
  showConfigDetailsModal.value = true
  console.log('查看详情:', selectedConfig.value)
  console.log('配置详情模态框状态:', showConfigDetailsModal.value)
  // 确保不显示其他模态框
  showDataSourceModal.value = false
  showDetailsModal.value = false
}

// 编辑配置
const editConfig = (index) => {
  // 设置编辑模式和索引
  isEditing.value = true
  editingIndex.value = index

  // 加载配置数据到表单
  const config = savedConfigurations.value[index]
  configName.value = config.name // 设置配置名称
  dbConfig.value = { ...config.dbConfig }
  sqlQuery.value = config.sqlQuery
  fields.value = [...config.fields]
  scheduleConfig.value = { ...config.scheduleConfig }

  // 模拟查询结果，以便编辑时能更好地展示数据
  queryResults.value = [
    { id: 1, name: '测试数据1', description: '这是第一条测试数据', created_at: '2023-01-01', updated_at: '2023-01-02' },
    { id: 2, name: '测试数据2', description: '这是第二条测试数据', created_at: '2023-01-03', updated_at: '2023-01-04' },
    { id: 3, name: '测试数据3', description: '这是第三条测试数据', created_at: '2023-01-05', updated_at: '2023-01-06' }
  ]

  // 模拟预览数据
  previewData.value = [...queryResults.value]
  filteredPreviewData.value = [...previewData.value]

  // 打开配置模态框
  showDataSourceModal.value = true
  // 确保不显示配置详情模态框
  showConfigDetailsModal.value = false
  // 确保不显示数据详情模态框
  showDetailsModal.value = false

  // 重置步骤到第一步，但用户可以自由跳转到任何已完成的步骤
  currentStep.value = 1
}

// 删除配置
const deleteConfig = (index) => {
  showCustomConfirm(`确定要删除配置 "${savedConfigurations.value[index].name}" 吗？`, '确认删除', async () => {
    try {
      // 获取要删除的配置ID
      const configId = savedConfigurations.value[index].id;

      // 调用后端API删除数据源
      const response = await del(`/api/data-sources/${configId}`);

      // 先获取要删除的DOM元素以添加动画效果
      const configToDelete = document.querySelector(`.saved-configurations table tbody tr:nth-child(${index + 1})`);

      if (configToDelete) {
        // 添加简单的删除动画效果
        configToDelete.style.opacity = '0';
        configToDelete.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
        configToDelete.style.height = configToDelete.offsetHeight + 'px';

        // 强制重排
        configToDelete.offsetHeight;

        // 设置高度为0以避免空白
        setTimeout(() => {
          configToDelete.style.height = '0';
          configToDelete.style.margin = '0';
          configToDelete.style.padding = '0';
          configToDelete.style.overflow = 'hidden';
          configToDelete.style.display = 'block';
        }, 10);

        // 等待动画完全完成后再刷新数据
        setTimeout(() => {
          // 从后端重新获取最新的数据源列表
          fetchDataSources();
          showCustomAlert(response.message || '配置已删除', '成功', 'success');
        }, 350);
      } else {
        // 没有找到DOM元素，直接刷新数据源列表
        fetchDataSources();
        showCustomAlert(response.message || '配置已删除', '成功', 'success');
      }
    } catch (error) {
      console.error('删除配置失败:', error);
      showCustomAlert(`删除失败: ${error.message || '网络错误或服务器不可用'}`, '错误', 'error');
    }
  });
}
// 关闭详情模态框
const closeConfigDetailsModal = () => {
  showConfigDetailsModal.value = false
}

// 同步数据源
const syncDataSource = (index) => {
  isSyncing.value = true

  // 获取选中的数据源配置
  const config = savedConfigurations.value[index]
  syncDataSourceConfig.value = { ...config }

  // 模拟执行SQL查询获取所有结果
  setTimeout(() => {
    // 这里应该调用实际的API来执行查询
    // 为了演示，我们使用模拟数据
    if (config.queryResults && config.queryResults.length > 0) {
      syncDataSourceResults.value = [...config.queryResults]
    } else {
      // 如果没有保存的查询结果，使用模拟数据
      syncDataSourceResults.value = Array.from({ length: 5 }, (_, i) => ({
        id: i + 1,
        name: `模拟数据 ${i + 1}`,
        value: Math.floor(Math.random() * 1000)
      }))
    }

    showSyncDataSourceModal.value = true
    isSyncing.value = false
  }, 500)
}

// 同步数据源配置到后端
const isSubmittingTask = ref(false)
const syncDataSourceConfigToBackend = async () => {
  if (!syncDataSourceConfig.value || !syncDataSourceConfig.value.id) {
    showCustomAlert('请先选择有效的数据源配置', '错误', 'error')
    return
  }

  isSubmittingTask.value = true

  try {
    // 构建API端点，包含dataSourceId
    const endpoint = `/api/new-tasks/sync-from-datasource/${syncDataSourceConfig.value.id}`

    // 调用后端API
    const response = await post(endpoint, {})

    // 处理响应
    if (response.code === 200) {
      showCustomAlert(response.message || '数据源配置同步成功!', '成功', 'success')
    } else {
      showCustomAlert(`同步失败: ${response.message || '未知错误'}`, '错误', 'error')
    }
  } catch (error) {
    console.error('同步数据源配置失败:', error)
    showCustomAlert(`同步失败: ${error.message || '网络错误或服务器不可用'}`, '错误', 'error')
  } finally {
    isSubmittingTask.value = false
  }
}

// 关闭同步数据源模态框
const closeSyncDataSourceModal = () => {
  showSyncDataSourceModal.value = false
}

// 保存数据源配置当前步骤
const currentStep = ref(1)

// 数据库配置
const dbConfig = ref({
  dbType: 'mysql',
  host: '192.168.78.213',
  port: 3306,
  database: 'vardb',
  username: 'vardb_user',
  password: 'vardb_pass',
  timeout: 30
})

// SQL查询
const sqlQuery = ref('select * from users')
const queryResults = ref([])

// 字段配置
const fields = ref([])
const newField = ref({
  name: '',
  displayName: '',
  isDisplayed: true,
  isPrimaryKey: false,
  hasIndex: false,
  searchType: 'text', // 默认设为文本搜索
  order: 0
})
const showAddFieldForm = ref(false)

// 定时任务配置
const scheduleConfig = ref({
  enabled: false,
  frequency: 'hour',
  interval: 1,
  startTime: '00:00',
  endTime: '23:59',
  daysOfWeek: [],
  daysOfMonth: 1,
  cronExpression: ''
})

// 预览数据
const previewData = ref([])
const filteredPreviewData = ref([])
const selectedRow = ref({})
const showDetailsModal = ref(false)

// 搜索过滤
const searchFilters = ref({})
const searchableFields = computed(() => {
  return fields.value.filter(field => field.isDisplayed)
})

// 检查是否可以进入下一步
const canProceed = computed(() => {
  if (currentStep.value === 1) {
    // 数据库配置验证
    return dbConfig.value.host && dbConfig.value.port &&
      dbConfig.value.database && dbConfig.value.username
  } else if (currentStep.value === 2) {
    // SQL查询验证
    return sqlQuery.value.trim() && queryResults.value.length > 0
  } else if (currentStep.value === 3) {
    // 字段配置验证
    return fields.value.length > 0
  } else if (currentStep.value === 4) {
    // 定时任务验证 - 总是可以继续
    return true
  } else if (currentStep.value === 5) {
    // 预览步骤 - 总是可以继续
    return true
  }
  return false
})

// 获取显示的字段
const displayedFields = computed(() => {
  return fields.value
    .filter(field => field.isDisplayed)
    .sort((a, b) => (a.order || 0) - (b.order || 0))
})

// 切换到指定步骤
const goToStep = (step) => {
  if (step <= currentStep.value || (step === currentStep.value + 1 && canProceed.value)) {
    currentStep.value = step
    // 切换步骤时隐藏添加字段表单
    showAddFieldForm.value = false
  }
}

// 切换添加字段表单显示状态
const toggleAddFieldForm = () => {
  showAddFieldForm.value = !showAddFieldForm.value
}

// 上一步
const prevStep = () => {
  if (currentStep.value > 1) {
    currentStep.value = currentStep.value - 1
  }
}

// 下一步
const nextStep = () => {
  if (currentStep.value < 5 && canProceed.value) {
    if (currentStep.value === 1) {
      // 数据库配置完成，进入SQL查询
      // 这里应该有实际的数据库连接逻辑
      // 模拟获取表结构
      fields.value = [
        { name: 'id', displayName: 'ID', isDisplayed: true, isPrimaryKey: true, order: 1, hasIndex: true, searchType: 'text' },
        { name: 'name', displayName: '名称', isDisplayed: true, isPrimaryKey: false, order: 2, hasIndex: false, searchType: 'text' },
        { name: 'description', displayName: '描述', isDisplayed: true, isPrimaryKey: false, order: 3, hasIndex: false, searchType: 'text' },
        { name: 'created_at', displayName: '创建时间', isDisplayed: true, isPrimaryKey: false, order: 4, hasIndex: false, searchType: 'text' },
        { name: 'updated_at', displayName: '更新时间', isDisplayed: false, isPrimaryKey: false, order: 5, hasIndex: false, searchType: 'text' }
      ]
    } else if (currentStep.value === 2) {
      // SQL查询完成，进入字段配置
      // 使用查询结果配置字段
      if (queryResults.value.length > 0) {
        fields.value = Object.keys(queryResults.value[0]).map(key => ({
          name: key,
          displayName: key,
          isDisplayed: true,
          isPrimaryKey: key === 'id', // 如果字段名为'id'，默认设为主键
          order: Object.keys(queryResults.value[0]).indexOf(key) + 1,
          hasIndex: key === 'id', // 如果字段名为'id'，默认设为索引
          searchType: 'text' // 默认设为文本搜索
        }))
        // 默认设置一些搜索类型
        if (fields.value.length > 1) {
          fields.value[1].searchType = 'dropdown'; // 第二个字段设为下拉搜索
        }
      }
    } else if (currentStep.value === 3) {
      // 字段配置完成，进入定时任务
    } else if (currentStep.value === 4) {
      // 定时任务配置完成，进入预览
      // 模拟预览数据 - 确保包含所有字段
      previewData.value = queryResults.value
        .map(row => {
          // 保留原始行的所有字段，而不仅限于displayedFields
          const completeRow = { ...row }
          return completeRow
        })
      // 初始化过滤后的数据
      filteredPreviewData.value = [...previewData.value]
      // 初始化搜索过滤器
      searchableFields.value.forEach(field => {
        searchFilters.value[field.name] = ''
      })
    }
    currentStep.value = currentStep.value + 1
  } else if (currentStep.value === 5) {
    // 完成配置
    showCustomAlert('数据源配置已完成!', '成功', 'success');
  }
}

// 居中弹窗相关状态
const showAlert = ref(false);
const alertMessage = ref('');
const alertTitle = ref('提示');
const alertType = ref('info'); // info, success, error

// 居中确认对话框相关状态
const showConfirm = ref(false);
const confirmMessage = ref('');
const confirmTitle = ref('确认操作');
let confirmCallback = null;

// 显示居中弹窗
const showCustomAlert = (message, title = '提示', type = 'info') => {
  alertMessage.value = message;
  alertTitle.value = title;
  alertType.value = type;
  showAlert.value = true;
};

// 显示居中确认对话框
const showCustomConfirm = (message, title = '确认操作', callback) => {
  confirmMessage.value = message;
  confirmTitle.value = title;
  confirmCallback = callback;
  showConfirm.value = true;
};

// 关闭居中弹窗
const closeAlert = () => {
  showAlert.value = false;
};

// 关闭居中确认对话框
const closeConfirm = () => {
  showConfirm.value = false;
  confirmCallback = null;
};

// 确认操作
const confirmAction = () => {
  if (typeof confirmCallback === 'function') {
    confirmCallback();
  }
  closeConfirm();
};

// 测试数据库连接
const testConnection = async () => {
  try {
    // 构建请求参数
    const params = {
      dbType: dbConfig.value.dbType,
      host: dbConfig.value.host,
      port: dbConfig.value.port,
      databaseName: dbConfig.value.database,
      username: dbConfig.value.username,
      password: dbConfig.value.password
    };

    // 调用后端API
    const response = await post('/api/datasource-configs/test-connection-with-params', params);

    // 处理响应
    if (response.code === 200) {
      showCustomAlert('数据库连接测试成功!', '成功', 'success');
    } else {
      showCustomAlert(`连接失败: ${response.message || '未知错误'}`, '错误', 'error');
    }
  } catch (error) {
    console.error('测试数据库连接失败:', error);
    showCustomAlert(`连接失败: ${error.message || '网络错误或服务器不可用'}`, '错误', 'error');
  }
}

// 执行SQL查询
const executeQuery = async () => {
  try {
    // 构建请求参数
    const params = {
      dbType: dbConfig.value.dbType,
      host: dbConfig.value.host,
      port: dbConfig.value.port,
      databaseName: dbConfig.value.database,
      username: dbConfig.value.username,
      password: dbConfig.value.password,
      sql: sqlQuery.value,
      limit: 5, // 设置默认查询限制
      timeoutSeconds: dbConfig.value.timeout || 30 // 使用数据库配置中的超时或默认30秒
    };

    // 调用后端API
    const response = await post('/api/datasource-configs/execute-query-with-params', params);

    // 处理响应
    if (response.code === 200) {
      // 根据后端返回的数据结构，实际结果在rows中
      queryResults.value = response.data?.rows || [];
      showCustomAlert('查询执行成功!', '成功', 'success');
    } else {
      showCustomAlert(`查询失败: ${response.message || '未知错误'}`, '错误', 'error');
    }
  } catch (error) {
    console.error('执行SQL查询失败:', error);
    showCustomAlert(`查询失败: ${error.message || '网络错误或服务器不可用'}`, '错误', 'error');
  }
}

// 频率变更处理
const onFrequencyChange = () => {
  // 根据选择的频率重置相关字段
  if (scheduleConfig.value.frequency === 'minute') {
    scheduleConfig.value.interval = 1
  } else if (scheduleConfig.value.frequency === 'hour') {
    scheduleConfig.value.interval = 1
  } else if (scheduleConfig.value.frequency === 'day') {
    scheduleConfig.value.interval = 1
    scheduleConfig.value.startTime = '00:00'
    scheduleConfig.value.endTime = '23:59'
  } else if (scheduleConfig.value.frequency === 'week') {
    scheduleConfig.value.interval = 1
    scheduleConfig.value.startTime = '00:00'
    scheduleConfig.value.endTime = '23:59'
    scheduleConfig.value.daysOfWeek = []
  } else if (scheduleConfig.value.frequency === 'month') {
    scheduleConfig.value.interval = 1
    scheduleConfig.value.startTime = '00:00'
    scheduleConfig.value.endTime = '23:59'
    scheduleConfig.value.daysOfMonth = 1
  } else if (scheduleConfig.value.frequency === 'custom') {
    scheduleConfig.value.cronExpression = ''
  }
}

// 添加新字段
const addNewField = () => {
  if (newField.value.name.trim()) {
    const newFieldCopy = { ...newField.value }
    newFieldCopy.order = fields.value.length + 1
    fields.value.push(newFieldCopy)

    // 重置新字段表单
    newField.value = {
      name: '',
      displayName: '',
      isDisplayed: true,
      hasIndex: false,
      searchType: 'none',
      order: 0
    }
  }
}

// 获取定时任务信息
const getScheduleInfo = () => {
  if (!scheduleConfig.value.enabled) return '未启用定时任务'

  let info = ''
  const { frequency, interval, startTime, endTime, daysOfWeek, daysOfMonth } = scheduleConfig.value

  switch (frequency) {
    case 'minute':
      info = `每${interval}分钟执行一次`
      break
    case 'hour':
      info = `每${interval}小时执行一次`
      break
    case 'day':
      info = `每${interval}天 ${startTime}至${endTime}执行一次`
      break
    case 'week':
      const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
      const selectedDays = daysOfWeek.length > 0
        ? daysOfWeek.map(day => weekdays[day]).join('、')
        : '未选择'
      info = `每${interval}周的${selectedDays} ${startTime}至${endTime}执行一次`
      break
    case 'month':
      info = `每${interval}个月的${daysOfMonth}号 ${startTime}至${endTime}执行一次`
      break
    case 'custom':
      info = `自定义Cron表达式: ${scheduleConfig.value.cronExpression}`
      break
  }

  return info
}

// 获取下拉选项
const getDropdownOptions = (fieldName) => {
  // 模拟获取下拉选项
  if (queryResults.value.length === 0) return []

  const options = new Set()
  queryResults.value.forEach(row => {
    if (row[fieldName] !== undefined && row[fieldName] !== null) {
      options.add(row[fieldName])
    }
  })

  return Array.from(options)
}

// 应用搜索
const applySearch = () => {
  filteredPreviewData.value = previewData.value.filter(row => {
    // 对每个设置了搜索类型的字段应用过滤
    return searchableFields.value.every(field => {
      const filterValue = searchFilters.value[field.name]
      // 如果该字段没有设置过滤值，或者没有搜索类型，则通过筛选
      if (!filterValue) return true

      const rowValue = row[field.name]
      if (rowValue === undefined || rowValue === null) return false

      // 应用搜索逻辑
      return String(rowValue).toLowerCase().includes(String(filterValue).toLowerCase())
    })
  })
}

// 重置搜索
const resetSearch = () => {
  searchableFields.value.forEach(field => {
    searchFilters.value[field.name] = ''
  })
  filteredPreviewData.value = [...previewData.value]
}

// 查看详情
const viewDetails = (row) => {
  selectedRow.value = row
  showDetailsModal.value = true
}

// 关闭详情模态框
const closeDetailsModal = () => {
  showDetailsModal.value = false
}

// 获取字段显示名称
const getFieldDisplayName = (fieldName) => {
  const field = fields.value.find(f => f.name === fieldName)
  return field ? field.displayName : fieldName
}

// 复制内容到剪贴板
const copyToClipboard = (text, event) => {
  // 处理不同类型的值
  let copyText = ''
  if (typeof text === 'object' && text !== null) {
    copyText = JSON.stringify(text, null, 2)
  } else if (text === undefined || text === null) {
    copyText = ''
  } else {
    copyText = String(text)
  }

  // 复制到剪贴板
  navigator.clipboard.writeText(copyText).then(() => {
    // 显示复制成功提示
    const button = event?.target
    if (button) {
      const originalText = button.textContent
      button.textContent = '已复制'
      setTimeout(() => {
        button.textContent = originalText
      }, 2000)
    } else {
      // 如果没有按钮元素（例如通过其他方式调用），显示全局提示
      alert('复制成功')
    }
  }).catch(err => {
    console.error('复制失败:', err)
    alert('复制失败，请手动复制')
  })
}

// 复制所有数据详情
const copyAllDetails = () => {
  let allDetails = ''
  Object.entries(selectedRow.value).forEach(([key, value]) => {
    const displayName = getFieldDisplayName(key)
    let valueText = ''
    if (typeof value === 'object' && value !== null) {
      valueText = JSON.stringify(value, null, 2)
    } else if (value === undefined || value === null) {
      valueText = '空'
    } else if (typeof value === 'boolean') {
      valueText = value ? '是' : '否'
    } else {
      valueText = String(value)
    }
    allDetails += `${displayName}: ${valueText}\n`
  })

  navigator.clipboard.writeText(allDetails).then(() => {
    alert('所有详情已复制到剪贴板')
  }).catch(err => {
    console.error('复制失败:', err)
    alert('复制失败，请手动复制')
  })
}

// 复制所有配置详情
const copyAllConfigDetails = () => {
  let allConfigDetails = ''

  // 基本信息
  allConfigDetails += '=== 基本信息 ===\n'
  allConfigDetails += `配置名称: ${selectedConfig.value.name}\n`
  allConfigDetails += `创建时间: ${selectedConfig.value.createdAt}\n\n`

  // 数据库配置
  allConfigDetails += '=== 数据库配置 ===\n'
  const db = selectedConfig.value.dbConfig
  allConfigDetails += `数据库类型: ${db.dbType}\n`
  allConfigDetails += `主机名: ${db.host}\n`
  allConfigDetails += `端口: ${db.port}\n`
  allConfigDetails += `数据库名称: ${db.database}\n`
  allConfigDetails += `用户名: ${db.username}\n`
  allConfigDetails += `密码: 已隐藏\n`
  allConfigDetails += `连接超时: ${db.timeout} 秒\n\n`

  // SQL查询
  allConfigDetails += '=== SQL查询 ===\n'
  allConfigDetails += `${selectedConfig.value.sqlQuery}\n\n`

  // 字段配置
  allConfigDetails += '=== 字段配置 ===\n'
  allConfigDetails += '字段名,显示名称,是否显示,搜索类型,是否索引,排序\n'
  selectedConfig.value.fields.forEach(field => {
    allConfigDetails += `${field.name},${field.displayName},${field.isDisplayed ? '是' : '否'},`
    allConfigDetails += `${field.searchType === 'text' ? '文本搜索' : field.searchType === 'dropdown' ? '下拉搜索' : '无搜索'},`
    allConfigDetails += `${field.hasIndex ? '是' : '否'},${field.order || '-'}\n`
  })
  allConfigDetails += '\n'

  // 定时任务配置
  allConfigDetails += '=== 定时任务配置 ===\n'
  const schedule = selectedConfig.value.scheduleConfig
  allConfigDetails += `是否启用: ${schedule.enabled ? '是' : '否'}\n`
  if (schedule.enabled) {
    allConfigDetails += `执行频率: ${schedule.frequency === 'minute' ? '每分钟' : schedule.frequency === 'hour' ? '每小时' : schedule.frequency === 'day' ? '每天' : schedule.frequency === 'week' ? '每周' : schedule.frequency === 'month' ? '每月' : '自定义'}\n`
    allConfigDetails += `间隔数量: ${schedule.interval}\n`
    if (['day', 'week', 'month'].includes(schedule.frequency)) {
      allConfigDetails += `执行时间范围: ${schedule.startTime} 至 ${schedule.endTime}\n`
    }
    if (schedule.frequency === 'week') {
      const days = schedule.daysOfWeek.length > 0 ? schedule.daysOfWeek.map(day => ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][day]).join('、') : '未选择'
      allConfigDetails += `每周执行日: ${days}\n`
    }
    if (schedule.frequency === 'month') {
      allConfigDetails += `每月执行日: ${schedule.daysOfMonth}\n`
    }
    if (schedule.frequency === 'custom') {
      allConfigDetails += `Cron表达式: ${schedule.cronExpression || '未设置'}\n`
    }
    allConfigDetails += `任务描述: ${getScheduleInfo()}\n`
  }

  navigator.clipboard.writeText(allConfigDetails).then(() => {
    alert('所有配置详情已复制到剪贴板')
  }).catch(err => {
    console.error('复制失败:', err)
    alert('复制失败，请手动复制')
  })
}
</script>
<style scoped>
.data-source-configuration {
  width: 100%;
}

/* 同步数据源单页面布局样式 */
.sync-data-source-container {
  padding: var(--spacing-lg);
  background-color: var(--bg-light);
  min-height: calc(100vh - var(--header-height));
}

.sync-content {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
  gap: var(--spacing-lg);
  margin-top: var(--spacing-lg);
}

.sync-section {
  background-color: var(--bg-white);
  border-radius: var(--border-radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.sync-section:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

/* 响应式调整 */
@media (max-width: 768px) {
  .sync-content {
    grid-template-columns: 1fr;
  }

  .sync-data-source-container {
    padding: var(--spacing-md);
  }
}

.saved-configurations {
  margin-bottom: var(--spacing-xl);
  padding: var(--spacing-xl);
  background-color: var(--bg-white);
  border-radius: var(--border-radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.saved-configurations:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.saved-configurations h3 {
  margin-top: 0;
  margin-bottom: var(--spacing-lg);
  font-size: var(--font-size-lg);
  color: var(--text-primary);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.saved-configurations h3::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 20px;
  background-color: var(--primary-color);
  border-radius: var(--border-radius-sm);
}

.no-config-message {
  text-align: center;
  color: var(--text-secondary);
  padding: var(--spacing-lg) 0;
}

.action-buttons-cell {
  display: flex;
  gap: var(--spacing-sm);
}

.detail-section {
  margin-bottom: var(--spacing-lg);
  padding-bottom: var(--spacing-lg);
  border-bottom: 1px solid var(--border-light);
}

.detail-section:last-child {
  border-bottom: none;
}

.detail-section h4 {
  margin-top: 0;
  margin-bottom: var(--spacing-md);
  font-size: var(--font-size-base);
  color: var(--text-primary);
  font-weight: 500;
}

.sql-query pre {
  background-color: var(--bg-light);
  padding: var(--spacing-md);
  border-radius: var(--border-radius-md);
  overflow-x: auto;
  margin: 0;
}

.schedule-details {
  margin-top: var(--spacing-sm);
  padding: var(--spacing-md);
  background-color: var(--bg-light);
  border-radius: var(--border-radius-md);
}

/* 已在下方定义具体颜色值，此处省略 */

.data-source-configuration {
  width: 100%;
}

.page-header {
  margin-bottom: var(--spacing-lg);
  padding-bottom: var(--spacing-md);
  border-bottom: 1px solid var(--border-light);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-md);
}

.page-header h2 {
  font-size: var(--font-size-xl);
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

/* 继承全局样式 */
.card {
  background-color: var(--bg-white);
  border-radius: var(--border-radius-md);
  box-shadow: var(--shadow-base);
  overflow: hidden;
  transition: box-shadow 0.3s ease;
}

.card:hover {
  box-shadow: var(--shadow-md);
}

/* 复制按钮样式 */
.copy-btn {
  background-color: var(--bg-light);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-sm);
  padding: var(--spacing-xs) var(--spacing-sm);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: all 0.2s ease;
  margin-left: auto;
}

.copy-btn:hover {
  background-color: var(--bg-primary-light);
  border-color: var(--border-primary);
}

.sql-copy-btn {
  margin-top: var(--spacing-sm);
  margin-left: 0;
}

/* JSON预览样式 */
.json-preview {
  background-color: var(--bg-light);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-sm);
  padding: var(--spacing-sm);
  margin: 0;
  font-size: var(--font-size-sm);
  font-family: var(--font-family-mono);
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* 详情项样式优化 */
.detail-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: var(--spacing-sm);
  padding: var(--spacing-sm);
  border-radius: var(--border-radius-sm);
  transition: background-color 0.2s ease;
}

.detail-item:hover {
  background-color: var(--bg-light);
}

.detail-label {
  width: 120px;
  min-width: 120px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-right: var(--spacing-md);
}

.detail-value {
  flex: 1;
  word-break: break-word;
}

/* 步骤样式 */
.steps-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--spacing-lg);
  flex-wrap: wrap;
  gap: var(--spacing-sm);
}

.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  opacity: 0.5;
  transition: all 0.3s ease;
  min-width: 100px;
}

.step.active {
  opacity: 1;
  font-weight: 500;
  color: var(--primary-color);
}

.step.completed {
  opacity: 1;
  color: var(--success-color);
}

.step-number {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background-color: var(--bg-light);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--spacing-xs);
  transition: all 0.3s ease;
}

.step.active .step-number {
  background-color: var(--primary-color);
  color: white;
}

.step.completed .step-number {
  background-color: var(--success-color);
  color: white;
}

.step-label {
  font-size: var(--font-size-sm);
  text-align: center;
}

.step-separator {
  height: 2px;
  background-color: var(--border-light);
  flex: 1;
  min-width: 20px;
  max-width: 80px;
}

.step-separator.completed {
  background-color: var(--success-color);
}

/* 步骤内容样式 */
.step-content {
  padding: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
}

/* 表单样式 */
.form-item {
  margin-bottom: var(--spacing-lg);
}

.form-label {
  display: block;
  margin-bottom: var(--spacing-xs);
  font-weight: 500;
  color: var(--text-regular);
}

.input {
  width: 100%;
  padding: var(--spacing-sm) var(--spacing-md);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-md);
  font-size: var(--font-size-base);
  transition: all 0.3s ease;
}

.input.small {
  width: 80px;
}

.select {
  width: 100%;
  padding: var(--spacing-sm) var(--spacing-md);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-md);
  font-size: var(--font-size-base);
  background-color: white;
  transition: all 0.3s ease;
}

.select.small {
  width: 120px;
}

.textarea {
  width: 100%;
  padding: var(--spacing-sm) var(--spacing-md);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-md);
  font-size: var(--font-size-base);
  resize: vertical;
  transition: all 0.3s ease;
}

.form-actions {
  margin-top: var(--spacing-lg);
  display: flex;
  justify-content: flex-start;
  gap: var(--spacing-md);
}

/* 表格样式 */
.table-container {
  overflow-x: auto;
  margin-top: var(--spacing-lg);
  border-radius: var(--border-radius-md);
  border: 1px solid var(--border-light);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-base);
}

.table th {
  background-color: var(--bg-light);
  color: var(--text-regular);
  font-weight: 500;
  text-align: left;
  padding: var(--spacing-md);
  border-bottom: 2px solid var(--border-light);
  position: relative;
  user-select: none;
}

.table th:hover {
  background-color: var(--bg-hover);
  cursor: pointer;
}

.table th::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background-color: var(--primary-color);
  transition: width 0.3s ease;
}

.table th:hover::after {
  width: 100%;
}

.table td {
  padding: var(--spacing-md);
  border-bottom: 1px solid var(--border-light);
  color: var(--text-regular);
  transition: all 0.3s ease;
}

.table tr:last-child td {
  border-bottom: none;
}

.table tr:hover {
  background-color: var(--bg-hover);
  transform: translateX(2px);
}

.table tr:hover td {
  color: var(--text-primary);
}

/* 添加字段部分样式 */
.add-field-section {
  margin-top: var(--spacing-lg);
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
}

.add-field-form {
  margin-top: var(--spacing-md);
  padding: var(--spacing-lg);
  background-color: var(--bg-light);
  border-radius: var(--border-radius-md);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: box-shadow 0.3s ease;
}

.add-field-form:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
}

.add-field-form h3 {
  color: var(--text-primary);
  font-size: var(--font-size-lg);
  margin-top: 0;
  margin-bottom: var(--spacing-md);
  font-weight: 500;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-lg);
}

/* 美化复选框样式 */
.form-item input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-top: 6px;
  cursor: pointer;
  position: relative;
  appearance: none;
  background-color: white;
  border: 2px solid var(--border-light);
  border-radius: 4px;
  transition: all 0.3s ease;
}

/* 按钮禁用状态样式 */
button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}

.form-item input[type="checkbox"]:checked {
  background-color: var(--primary-color);
  border-color: var(--primary-color);
}

.form-item input[type="checkbox"]:checked::after {
  content: "✓";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: white;
  font-size: 14px;
  font-weight: bold;
}

.form-item input[type="checkbox"]:hover {
  border-color: var(--primary-color);
}

.form-item input[type="checkbox"]:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.3);
}

/* 美化输入框和下拉选择框 */
.form-item .input,
.form-item .select {
  border: 2px solid var(--border-light);
  transition: all 0.3s ease;
}

.form-item .input:focus,
.form-item .select:focus {
  border-color: var(--primary-color);
  outline: none;
  box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.3);
}

.form-item .select {
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  padding-right: 40px;
  appearance: none;
}

/* 美化标签样式 */
.form-label {
  display: block;
  margin-bottom: var(--spacing-xs);
  font-weight: 500;
  color: var(--text-regular);
  font-size: var(--font-size-base);
}

/* 按钮样式补充 */
.btn-secondary {
  background-color: #6c757d;
  color: white;
}

.btn-secondary:hover {
  background-color: #5a6268;
}

.btn-danger {
  background-color: #dc3545;
  color: white;
}

.btn-danger:hover {
  background-color: #c82333;
}

/* 美化添加字段按钮 */
.add-field-section button.btn-primary {
  background-color: var(--primary-color);
  color: white;
  border: none;
  padding: var(--spacing-sm) var(--spacing-lg);
  border-radius: var(--border-radius-md);
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 500;
}

.add-field-section button.btn-primary:hover {
  background-color: var(--primary-hover);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(66, 153, 225, 0.3);
}

.add-field-section button.btn-primary:active {
  transform: translateY(0);
  box-shadow: 0 1px 4px rgba(66, 153, 225, 0.3);
}

/* 时间范围样式 */
.time-range {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.time-range-separator {
  color: var(--text-secondary);
}

/* 定时任务信息样式 */
.schedule-info {
  margin-bottom: var(--spacing-lg);
  padding: var(--spacing-md);
  background-color: var(--bg-light);
  border-radius: var(--border-radius-md);
}

.schedule-info-content {
  margin-top: var(--spacing-sm);
}

/* 搜索过滤样式 */
.search-filter {
  margin-bottom: var(--spacing-lg);
  padding: var(--spacing-md);
  background-color: var(--bg-light);
  border-radius: var(--border-radius-md);
}

.search-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--spacing-md);
  margin: var(--spacing-md) 0;
}

.search-field-item {
  margin-bottom: 0;
}

.table th {
  font-weight: 500;
  color: var(--text-regular);
  background-color: var(--bg-light);
}

.table tr:hover {
  background-color: var(--bg-hover);
}

/* 查询结果样式 */
.query-results {
  margin-top: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
  padding-top: var(--spacing-lg);
}

.result-count {
  margin-top: var(--spacing-md);
  text-align: right;
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
}

/* 同步成功消息样式 */
.success-message {
  padding: var(--spacing-lg);
  background-color: #d4edda;
  color: #155724;
  border-radius: var(--border-radius-md);
  text-align: center;
  font-weight: 500;
}

/* 定时任务样式 */
.schedule-details {
  margin-top: var(--spacing-md);
  padding: var(--spacing-md);
  background-color: var(--bg-light);
  border-radius: var(--border-radius-md);
}

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-md);
}

.checkbox-group label {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}

/* 操作按钮 */
.action-buttons {
  display: flex;
  justify-content: flex-end;
  padding: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
  gap: var(--spacing-md);
}

/* 居中弹窗样式 */
.alert-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1500;
  animation: fadeIn 0.3s ease;
}

.alert-modal-content {
  background-color: white;
  border-radius: var(--border-radius-lg);
  box-shadow: var(--shadow-lg);
  width: 90%;
  max-width: 450px;
  overflow: hidden;
  animation: slideIn 0.3s ease;
}

.alert-modal-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--border-light);
  background-color: var(--bg-light);
}

.alert-modal-header h4 {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--font-size-lg);
  font-weight: 500;
}

.alert-modal-body {
  padding: var(--spacing-xl);
  text-align: center;
}

.alert-modal-body p {
  margin: 0;
  color: var(--text-regular);
  font-size: var(--font-size-base);
  line-height: 1.6;
}

.alert-modal-footer {
  padding: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
  text-align: center;
}

.alert-modal-footer .btn {
  min-width: 100px;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 详情模态框 */
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(2px);
}

.modal-content {
  background-color: var(--bg-white);
  border-radius: var(--border-radius-md);
  box-shadow: var(--shadow-lg);
  width: 90%;
  max-width: 600px;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  animation: modalFadeIn 0.3s ease;
}

@keyframes modalFadeIn {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.modal-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--border-light);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-title {
  font-size: var(--font-size-lg);
  font-weight: 500;
  color: var(--text-primary);
  margin: 0;
}

.modal-body {
  padding: var(--spacing-lg);
  overflow-y: auto;
  flex: 1;
}

.detail-item {
  margin-bottom: var(--spacing-md);
  padding-bottom: var(--spacing-md);
  border-bottom: 1px solid var(--border-light);
  display: flex;
}

.detail-label {
  font-weight: 500;
  min-width: 120px;
}

.detail-value {
  flex: 1;
}

.modal-footer {
  padding: var(--spacing-lg);
  border-top: 1px solid var(--border-light);
  display: flex;
  justify-content: center;
  gap: var(--spacing-md);
}

/* 响应式调整 */
@media (max-width: 768px) {
  .steps-container {
    flex-direction: column;
    align-items: flex-start;
  }

  .step {
    flex-direction: row;
    min-width: auto;
    gap: var(--spacing-xs);
  }

  .step-number {
    margin-bottom: 0;
  }

  .step-separator {
    width: 2px;
    height: 30px;
    min-width: auto;
    max-width: auto;
  }
}

/* 预览界面样式 */
.preview {
  animation: fadeIn 0.5s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.preview-section {
  margin-bottom: var(--spacing-lg);
}

.preview-section .card {
  background-color: var(--bg-white);
  border-radius: var(--border-radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.3s, box-shadow 0.3s;
  margin-bottom: var(--spacing-lg);
}

.preview-section .card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.preview-section .card-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--border-light);
  background-color: var(--bg-light);
}

.preview-section .card-body {
  padding: var(--spacing-lg);
}

.preview-section .section-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.preview-section .section-title::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 20px;
  background-color: var(--primary-color);
  border-radius: var(--border-radius-sm);
}

.preview-section .info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-lg);
}

.preview-section .info-item {
  margin-bottom: var(--spacing-md);
  display: flex;
  align-items: center;
  padding: var(--spacing-sm);
  border-radius: var(--border-radius-sm);
  transition: background-color 0.2s ease;
}

.preview-section .info-item:hover {
  background-color: var(--bg-light);
}

.preview-section .info-label {
  font-weight: 500;
  margin-right: var(--spacing-md);
  color: var(--text-secondary);
  min-width: 100px;
}

.preview-section .info-value {
  color: var(--text-primary);
  flex: 1;
  word-break: break-word;
}

.preview-section .sql-query-preview {
  margin-bottom: var(--spacing-lg);
}

.preview-section .sql-code {
  padding: var(--spacing-md);
  background-color: var(--bg-light);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-md);
  overflow-x: auto;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--text-primary);
}

/* 统计卡片样式 */
.query-stats,
.field-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-lg);
}

.stat-item {
  flex: 1 1 150px;
  padding: var(--spacing-lg);
  background-color: var(--bg-white);
  border-radius: var(--border-radius-md);
  text-align: center;
  border: 1px solid var(--border-light);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s, box-shadow 0.2s;
}

.stat-item:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.stat-label {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  margin-bottom: var(--spacing-xs);
}

.stat-value {
  font-size: var(--font-size-xl);
  font-weight: 600;
  color: var(--primary-color);
}

/* 状态徽章样式 */
.status-badge {
  display: inline-block;
  padding: var(--spacing-xs) var(--spacing-sm);
  border-radius: var(--border-radius-full);
  font-size: var(--font-size-xs);
  font-weight: 500;
  transition: all 0.2s ease;
}

.status-active {
  background-color: var(--bg-success-light);
  color: var(--success-color);
  border: 1px solid var(--border-success);
}

.status-inactive {
  background-color: var(--bg-danger-light);
  color: var(--danger-color);
  border: 1px solid var(--border-danger);
}

/* 定时任务描述样式 */
.schedule-description {
  padding: var(--spacing-md);
  background-color: var(--bg-primary-light);
  border-radius: var(--border-radius-md);
  border-left: 4px solid var(--primary-color);
}

.schedule-description .info-value {
  font-style: italic;
  color: var(--primary-color);
}

/* 分页控件样式 */
.pagination-container {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-md);
  margin-top: var(--spacing-lg);
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--border-base);
  flex-wrap: wrap;
}

.page-info {
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  margin: 0 var(--spacing-md);
}

.page-size-selector {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  margin-left: auto;
}

.page-size-selector select {
  padding: var(--spacing-xs) var(--spacing-sm);
  border: 1px solid var(--border-base);
  border-radius: var(--border-radius-base);
  background-color: white;
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  cursor: pointer;
}

.page-size-selector select:focus {
  outline: none;
  border-color: var(--primary-color);
}

/* 数据源卡片容器 - 自适应布局 */
.datasources-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 24px;
  padding: 24px;
}

/* 数据源卡片样式 */
.datasource-card {
  background: var(--bg-white, #ffffff);
  border: 1px solid var(--border-base, #e5e7eb);
  border-radius: 12px;
  padding: 24px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  position: relative;
  overflow: hidden;
  min-height: 280px;
  display: flex;
  flex-direction: column;
}

.datasource-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
  border-color: var(--primary-color, #667eea);
}

/* 数据源头部 */
.datasource-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-light, #f0f0f0);
}

.datasource-title-section {
  flex: 1;
  min-width: 0;
}

.datasource-name {
  margin: 0 0 8px 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--text-primary, #333);
  line-height: 1.3;
  word-break: break-word;
}

.db-type {
  font-size: 12px;
  color: var(--text-secondary, #666);
  background: var(--bg-light, #f8f9fa);
  padding: 4px 8px;
  border-radius: 6px;
  font-style: italic;
  display: inline-block;
  max-width: 100%;
  word-break: break-word;
}

.datasource-status {
  display: flex;
  align-items: center;
}

.status-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #10b981;
  box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
}

.status-indicator.active {
  background: #10b981;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(16, 185, 129, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
  }
}

/* 数据源内容 */
.datasource-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.connection-info-section {
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
  border: 1px solid var(--border-light, #e5e7eb);
  border-radius: 8px;
  padding: 16px;
  transition: all 0.3s ease;
  flex: 1;
}

.connection-info-section:hover {
  border-color: var(--primary-color, #667eea);
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.15);
  background: linear-gradient(135deg, #f0f4ff 0%, #ffffff 100%);
}

.section-title {
  font-size: 12px;
  color: var(--text-secondary, #6b7280);
  margin-bottom: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-light, #e5e7eb);
}

.connection-details {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.detail-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
}

.detail-label {
  font-size: 12px;
  color: var(--text-secondary, #6b7280);
  font-weight: 500;
}

.detail-value {
  font-size: 12px;
  color: var(--text-primary, #333);
  font-weight: 600;
  text-align: right;
  max-width: 60%;
  word-break: break-word;
}

/* 数据源操作按钮 */
.datasource-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-light, #e5e7eb);
  flex-wrap: wrap;
}

.datasource-actions .btn {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  padding: 8px 12px;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.datasource-actions .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 工具栏样式 */
.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--border-base);
  flex-wrap: wrap;
  gap: var(--spacing-lg);
}

.toolbar h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--text-primary);
}

/* 加载状态样式 */
.loading-state {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 40px;
  color: var(--text-secondary);
}

.spinner {
  width: 20px;
  height: 20px;
  border: 2px solid var(--border-light);
  border-top: 2px solid var(--primary-color);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 空状态消息样式 */
.no-config-message {
  text-align: center;
  padding: 40px 20px;
  color: var(--text-secondary, #6b7280);
  font-size: 16px;
  font-style: italic;
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
  border: 2px dashed var(--border-light, #e5e7eb);
  border-radius: 12px;
  margin: 24px;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .datasources-grid {
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 20px;
    padding: 20px;
  }
}

@media (max-width: 768px) {
  .toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .datasources-grid {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 16px;
  }

  .datasource-card {
    padding: 20px;
    min-height: 240px;
  }

  .datasource-name {
    font-size: 16px;
  }

  .datasource-actions {
    flex-direction: column;
  }

  .datasource-actions .btn {
    flex: none;
  }

  .preview-section .info-grid {
    grid-template-columns: 1fr;
  }

  .query-stats,
  .field-stats {
    flex-direction: column;
  }

  .stat-item {
    flex: 1 1 100%;
  }

  .pagination-container {
    flex-direction: column;
    gap: var(--spacing-sm);
  }

  .page-size-selector {
    margin-left: 0;
    margin-top: var(--spacing-sm);
  }
}
</style>